
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>tigramite.independence_tests.oracle_conditional_independence &#8212; Tigramite 5.2 documentation</title>
    <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
    <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
   
  <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
  
  
  <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />

  </head><body>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  <h1>Source code for tigramite.independence_tests.oracle_conditional_independence</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Tigramite causal discovery for time series.&quot;&quot;&quot;</span>

<span class="c1"># Author: Jakob Runge &lt;jakob@jakob-runge.com&gt;</span>
<span class="c1">#</span>
<span class="c1"># License: GNU General Public License v3.0</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span><span class="p">,</span> <span class="n">OrderedDict</span>
<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">combinations</span><span class="p">,</span> <span class="n">permutations</span>


<div class="viewcode-block" id="OracleCI"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI">[docs]</a><span class="k">class</span> <span class="nc">OracleCI</span><span class="p">:</span>
<span class="w">    </span><span class="sa">r</span><span class="sd">&quot;&quot;&quot;Oracle of conditional independence test X _|_ Y | Z given a graph.</span>

<span class="sd">    Class around link_coeff causal ground truth. X _|_ Y | Z is based on</span>
<span class="sd">    assessing whether X and Y are d-separated given Z in the graph.</span>

<span class="sd">    Class can be used just like a Tigramite conditional independence class</span>
<span class="sd">    (e.g., ParCorr). The main use is for unit testing of PCMCI methods.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">        Causal graph.</span>
<span class="sd">    links : dict</span>
<span class="sd">        Dictionary of form {0:[(0, -1), ...], 1:[...], ...}.</span>
<span class="sd">        Alternatively can also digest {0: [((0, -1), coeff, func)], ...}.</span>
<span class="sd">    observed_vars : None or list, optional (default: None)</span>
<span class="sd">        Subset of keys in links definining which variables are </span>
<span class="sd">        observed. If None, then all variables are observed.</span>
<span class="sd">    selection_vars : None or list, optional (default: None)</span>
<span class="sd">        Subset of keys in links definining which variables are </span>
<span class="sd">        selected (= always conditioned on at every time lag).</span>
<span class="sd">        If None, then no variables are selected.</span>
<span class="sd">    verbosity : int, optional (default: 0)</span>
<span class="sd">        Level of verbosity.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># documentation</span>
    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">measure</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Concrete property to return the measure of the independence test</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_measure</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                 <span class="n">links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">observed_vars</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">selection_vars</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">graph</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">graph_is_mag</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                 <span class="n">tau_max</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">tau_max</span> <span class="o">=</span> <span class="n">tau_max</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">graph_is_mag</span> <span class="o">=</span> <span class="n">graph_is_mag</span>

        <span class="k">if</span> <span class="n">links</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">graph</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Either links or graph must be specified!&quot;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># Get canonical DAG from graph, potentially interpreted as MAG</span>
                <span class="c1"># self.tau_max = graph.shape[2]</span>
                <span class="p">(</span><span class="n">links</span><span class="p">,</span> 
                 <span class="n">observed_vars</span><span class="p">,</span> 
                 <span class="n">selection_vars</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_links_from_graph</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
                <span class="c1"># # TODO make checks and tau_max?</span>
                <span class="c1"># self.graph = graph</span>


        <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">=</span> <span class="n">verbosity</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_measure</span> <span class="o">=</span> <span class="s1">&#39;oracle_ci&#39;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">confidence</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">links</span> <span class="o">=</span> <span class="n">links</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">links</span><span class="p">)</span>
        <span class="c1"># self.tau_max = self._get_minmax_lag(self.links)</span>

        <span class="c1"># Initialize already computed dsepsets of X, Y, Z</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span> <span class="o">=</span> <span class="p">{}</span>

        <span class="c1"># Initialize observed vars</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span> <span class="o">=</span> <span class="n">observed_vars</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">)</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">))):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;observed_vars must be subset of range(N).&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;observed_vars must ordered.&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">)):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;observed_vars must not contain duplicates.&quot;</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="o">=</span> <span class="n">selection_vars</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">)</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">))):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selection_vars must be subset of range(N).&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selection_vars must ordered.&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">)):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selection_vars must not contain duplicates.&quot;</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="c1"># ToDO: maybe allow to use user-tau_max, otherwise deduced from links</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_graph_from_links</span><span class="p">(</span><span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>

<div class="viewcode-block" id="OracleCI.set_dataframe"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.set_dataframe">[docs]</a>    <span class="k">def</span> <span class="nf">set_dataframe</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Dummy function.&quot;&quot;&quot;</span>
        <span class="k">pass</span></div>

    <span class="k">def</span> <span class="nf">_check_XYZ</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Checks variables X, Y, Z.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y, Z : list of tuples</span>
<span class="sd">            For a dependence measure I(X;Y|Z), Y is of the form [(varY, 0)],</span>
<span class="sd">            where var specifies the variable index. X typically is of the form</span>
<span class="sd">            [(varX, -tau)] with tau denoting the time lag and Z can be</span>
<span class="sd">            multivariate [(var1, -lag), (var2, -lag), ...] .</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        X, Y, Z : tuple</span>
<span class="sd">            Cleaned X, Y, Z.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Get the length in time and the number of nodes</span>
        <span class="n">N</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span>

        <span class="c1"># Remove duplicates in X, Y, Z</span>
        <span class="n">X</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">OrderedDict</span><span class="o">.</span><span class="n">fromkeys</span><span class="p">(</span><span class="n">X</span><span class="p">))</span>
        <span class="n">Y</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">OrderedDict</span><span class="o">.</span><span class="n">fromkeys</span><span class="p">(</span><span class="n">Y</span><span class="p">))</span>
        <span class="n">Z</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">OrderedDict</span><span class="o">.</span><span class="n">fromkeys</span><span class="p">(</span><span class="n">Z</span><span class="p">))</span>

        <span class="c1"># If a node in Z occurs already in X or Y, remove it from Z</span>
        <span class="n">Z</span> <span class="o">=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">Z</span> <span class="k">if</span> <span class="p">(</span><span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">X</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">)]</span>

        <span class="c1"># Check that all lags are non-positive and indices are in [0,N-1]</span>
        <span class="n">XYZ</span> <span class="o">=</span> <span class="n">X</span> <span class="o">+</span> <span class="n">Y</span> <span class="o">+</span> <span class="n">Z</span>
        <span class="n">dim</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)</span>
        <span class="c1"># Ensure that XYZ makes sense</span>
        <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)</span><span class="o">.</span><span class="n">shape</span> <span class="o">!=</span> <span class="p">(</span><span class="n">dim</span><span class="p">,</span> <span class="mi">2</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;X, Y, Z must be lists of tuples in format&quot;</span>
                             <span class="s2">&quot; [(var, -lag),...], eg., [(2, -2), (1, 0), ...]&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)[:,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;nodes are </span><span class="si">%s</span><span class="s2">, &quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)</span> <span class="o">+</span>
                             <span class="s2">&quot;but all lags must be non-positive&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">N</span><span class="p">)</span>
                <span class="ow">or</span> <span class="n">np</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;var indices </span><span class="si">%s</span><span class="s2">,&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">XYZ</span><span class="p">)[:,</span> <span class="mi">0</span><span class="p">])</span> <span class="o">+</span>
                             <span class="s2">&quot; but must be in [0, </span><span class="si">%d</span><span class="s2">]&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">N</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">Y</span><span class="p">)[:,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Y-nodes are </span><span class="si">%s</span><span class="s2">, &quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">Y</span><span class="p">)</span> <span class="o">+</span>
                             <span class="s2">&quot;but one of the Y-nodes must have zero lag&quot;</span><span class="p">)</span>

        <span class="k">return</span> <span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_get_lagged_parents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var_lag</span><span class="p">,</span> <span class="n">exclude_contemp</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">X</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">causal_children</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to yield lagged parents for var_lag from</span>
<span class="sd">        self.links_coeffs.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        var_lag : tuple</span>
<span class="sd">            Tuple of variable and lag which is assumed &lt;= 0.</span>
<span class="sd">        exclude_contemp : bool</span>
<span class="sd">            Whether contemporaneous links should be exluded.</span>

<span class="sd">        Yields</span>
<span class="sd">        ------</span>
<span class="sd">        Next lagged parent.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">var</span><span class="p">,</span> <span class="n">lag</span> <span class="o">=</span> <span class="n">var_lag</span>

        <span class="k">for</span> <span class="n">link_props</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">[</span><span class="n">var</span><span class="p">]:</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">link_props</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
                <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
                <span class="n">coeff</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link_props</span>
                <span class="n">coeff</span> <span class="o">=</span> <span class="mf">1.</span>
            <span class="k">if</span> <span class="n">coeff</span> <span class="o">!=</span> <span class="mf">0.</span><span class="p">:</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">exclude_contemp</span> <span class="ow">and</span> <span class="n">lag</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
                    <span class="k">if</span> <span class="n">only_non_causal_paths</span><span class="p">:</span>
                        <span class="k">if</span> <span class="ow">not</span> <span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="n">X</span> <span class="ow">and</span> <span class="n">var_lag</span> <span class="ow">in</span> <span class="n">causal_children</span><span class="p">):</span>
                            <span class="k">yield</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="k">yield</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_get_children</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to get children from links.</span>

<span class="sd">        Note that for children the lag is positive.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        children : dict</span>
<span class="sd">            Dictionary of form {0:[(0, 1), (3, 0), ...], 1:[], ...}.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>
        <span class="n">children</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">j</span><span class="p">,</span> <span class="p">[])</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">)])</span>

        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">link_props</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">link_props</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
                    <span class="n">coeff</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link_props</span>
                    <span class="n">coeff</span> <span class="o">=</span> <span class="mf">1.</span>
                <span class="k">if</span> <span class="n">coeff</span> <span class="o">!=</span> <span class="mf">0.</span><span class="p">:</span>
                    <span class="n">children</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)))</span>

        <span class="k">return</span> <span class="n">children</span>

    <span class="k">def</span> <span class="nf">_get_lagged_children</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var_lag</span><span class="p">,</span> <span class="n">children</span><span class="p">,</span> <span class="n">exclude_contemp</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
           <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">X</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">causal_children</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to yield lagged children for var_lag from children.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        var_lag : tuple</span>
<span class="sd">            Tuple of variable and lag which is assumed &lt;= 0.</span>
<span class="sd">        children : dict</span>
<span class="sd">            Dictionary of form {0:[(0, 1), (3, 0), ...], 1:[], ...}.</span>
<span class="sd">        exclude_contemp : bool</span>
<span class="sd">            Whether contemporaneous links should be exluded.</span>

<span class="sd">        Yields</span>
<span class="sd">        ------</span>
<span class="sd">        Next lagged child.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">var</span><span class="p">,</span> <span class="n">lag</span> <span class="o">=</span> <span class="n">var_lag</span>
        <span class="c1"># lagged_parents = []</span>

        <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">children</span><span class="p">[</span><span class="n">var</span><span class="p">]:</span>
            <span class="n">k</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">child</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">exclude_contemp</span> <span class="ow">and</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
                <span class="c1"># lagged_parents.append((i, lag + tau))</span>
                <span class="k">if</span> <span class="n">only_non_causal_paths</span><span class="p">:</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">var_lag</span> <span class="ow">in</span> <span class="n">X</span> <span class="ow">and</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="n">causal_children</span><span class="p">):</span>
                        <span class="k">yield</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">yield</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">lag</span> <span class="o">+</span> <span class="n">tau</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_get_non_blocked_ancestors</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;non_repeating&#39;</span><span class="p">,</span>
                                    <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to return the non-blocked ancestors of variables Y.</span>

<span class="sd">        Returns a dictionary of ancestors for every y in Y. y is a tuple (</span>
<span class="sd">        var, lag) where lag &lt;= 0. All ancestors with directed paths towards y</span>
<span class="sd">        that are not blocked by conditions in conds are included. In mode</span>
<span class="sd">        &#39;non_repeating&#39; an ancestor X^i_{t-\tau_i} with link X^i_{t-\tau_i}</span>
<span class="sd">        --&gt; X^j_{ t-\tau_j} is only included if X^i_{t&#39;-\tau_i} --&gt; X^j_{</span>
<span class="sd">        t&#39;-\tau_j} is not already part of the ancestors. The most lagged</span>
<span class="sd">        ancestor for every variable X^i defines the maximum ancestral time</span>
<span class="sd">        lag, which is also returned. In mode &#39;max_lag&#39; ancestors are included</span>
<span class="sd">        up to the maximum time lag max_lag.</span>

<span class="sd">        It&#39;s main use is to return the maximum ancestral time lag max_lag of</span>
<span class="sd">        y in Y for every variable in self.links_coeffs.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        Y : list of tuples</span>
<span class="sd">            Of the form [(var, -tau)], where var specifies the variable</span>
<span class="sd">            index and tau the time lag.</span>
<span class="sd">        conds : list of tuples</span>
<span class="sd">            Of the form [(var, -tau)], where var specifies the variable</span>
<span class="sd">            index and tau the time lag.</span>
<span class="sd">        mode : {&#39;non_repeating&#39;, &#39;max_lag&#39;}</span>
<span class="sd">            Whether repeating links should be excluded or ancestors should be</span>
<span class="sd">            followed up to max_lag.</span>
<span class="sd">        max_lag : int</span>
<span class="sd">            Maximum time lag to include ancestors.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        ancestors : dict</span>
<span class="sd">            Includes ancestors for every y in Y.</span>
<span class="sd">        max_lag : int</span>
<span class="sd">            Maximum time lag to include ancestors.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">def</span> <span class="nf">_repeating</span><span class="p">(</span><span class="n">link</span><span class="p">,</span> <span class="n">seen_links</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Returns True if a link or its time-shifted version is already</span>
<span class="sd">            included in seen_links.&quot;&quot;&quot;</span>
            <span class="n">i</span><span class="p">,</span> <span class="n">taui</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span><span class="p">,</span> <span class="n">tauj</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

            <span class="k">for</span> <span class="n">seen_link</span> <span class="ow">in</span> <span class="n">seen_links</span><span class="p">:</span>
                <span class="n">seen_i</span><span class="p">,</span> <span class="n">seen_taui</span> <span class="o">=</span> <span class="n">seen_link</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
                <span class="n">seen_j</span><span class="p">,</span> <span class="n">seen_tauj</span> <span class="o">=</span> <span class="n">seen_link</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

                <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">seen_i</span> <span class="ow">and</span> <span class="n">j</span> <span class="o">==</span> <span class="n">seen_j</span>
                    <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tauj</span><span class="o">-</span><span class="n">taui</span><span class="p">)</span> <span class="o">==</span> <span class="nb">abs</span><span class="p">(</span><span class="n">seen_tauj</span><span class="o">-</span><span class="n">seen_taui</span><span class="p">)):</span>
                    <span class="k">return</span> <span class="kc">True</span>

            <span class="k">return</span> <span class="kc">False</span>

        <span class="k">if</span> <span class="n">conds</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">conds</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="n">conds</span> <span class="o">=</span> <span class="p">[</span><span class="n">z</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">conds</span> <span class="k">if</span> <span class="n">z</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">]</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>

        <span class="c1"># Initialize max. ancestral time lag for every N</span>
        <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;non_repeating&#39;</span><span class="p">:</span>
            <span class="n">max_lag</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">max_lag</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;max_lag must be set in mode = &#39;max_lag&#39;&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">selection_var</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">:</span>
                <span class="c1"># print (selection_var, conds)</span>
                <span class="c1"># print([(selection_var, -tau_sel) for tau_sel in range(0, max_lag + 1)])</span>
                <span class="n">conds</span> <span class="o">+=</span> <span class="p">[(</span><span class="n">selection_var</span><span class="p">,</span> <span class="o">-</span><span class="n">tau_sel</span><span class="p">)</span> <span class="k">for</span> <span class="n">tau_sel</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">max_lag</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>

        <span class="n">ancestors</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">y</span><span class="p">,</span> <span class="p">[])</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">])</span>

        <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">:</span>
            <span class="n">j</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">y</span>   <span class="c1"># tau &lt;= 0</span>
            <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;non_repeating&#39;</span><span class="p">:</span>
                <span class="n">max_lag</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">max_lag</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))</span>
            <span class="n">seen_links</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="n">this_level</span> <span class="o">=</span> <span class="p">[</span><span class="n">y</span><span class="p">]</span>
            <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">next_level</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">varlag</span> <span class="ow">in</span> <span class="n">this_level</span><span class="p">:</span>
                    <span class="k">for</span> <span class="n">par</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_lagged_parents</span><span class="p">(</span><span class="n">varlag</span><span class="p">):</span>
                        <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">par</span>
                        <span class="k">if</span> <span class="n">par</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">conds</span> <span class="ow">and</span> <span class="n">par</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ancestors</span><span class="p">[</span><span class="n">y</span><span class="p">]:</span>
                            <span class="k">if</span> <span class="p">((</span><span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;non_repeating&#39;</span> <span class="ow">and</span>
                                <span class="ow">not</span> <span class="n">_repeating</span><span class="p">((</span><span class="n">par</span><span class="p">,</span> <span class="n">varlag</span><span class="p">),</span> <span class="n">seen_links</span><span class="p">))</span> <span class="ow">or</span>
                                <span class="p">(</span><span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;max_lag&#39;</span> <span class="ow">and</span>
                                 <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">max_lag</span><span class="p">))):</span>
                                    <span class="n">ancestors</span><span class="p">[</span><span class="n">y</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">par</span><span class="p">)</span>
                                    <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;non_repeating&#39;</span><span class="p">:</span>
                                        <span class="n">max_lag</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">max_lag</span><span class="p">,</span>
                                                         <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))</span>
                                    <span class="n">next_level</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">par</span><span class="p">)</span>
                                    <span class="n">seen_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">par</span><span class="p">,</span> <span class="n">varlag</span><span class="p">))</span>

                <span class="n">this_level</span> <span class="o">=</span> <span class="n">next_level</span>

        <span class="k">return</span> <span class="n">ancestors</span><span class="p">,</span> <span class="n">max_lag</span>

    <span class="k">def</span> <span class="nf">_get_maximum_possible_lag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">XYZ</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to return the maximum time lag of any confounding path.</span>

<span class="sd">        This is still based on a conjecture!</span>

<span class="sd">        The conjecture states that if and only if X and Y are d-connected given Z</span>
<span class="sd">        in a stationary DAG, then there exists a confounding path with a maximal</span>
<span class="sd">        time lag (i.e., the node on that path with maximal lag) given as follows:</span>
<span class="sd">        For any node in XYZ consider all non-repeating causal paths from the past</span>
<span class="sd">        to that node, where non-repeating means that a link X^i_{t-\tau_i}</span>
<span class="sd">        --&gt; X^j_{ t-\tau_j} is only traversed if X^i_{t&#39;-\tau_i} --&gt; X^j_{</span>
<span class="sd">        t&#39;-\tau_j} is not already part of that path. The most lagged</span>
<span class="sd">        ancestor for every variable node in XYZ defines the maximum ancestral time</span>
<span class="sd">        lag, which is returned.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        XYZ : list of tuples</span>
<span class="sd">            Of the form [(var, -tau)], where var specifies the variable</span>
<span class="sd">            index and tau the time lag.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        max_lag : int</span>
<span class="sd">            Maximum time lag of non-repeating causal path ancestors.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">def</span> <span class="nf">_repeating</span><span class="p">(</span><span class="n">link</span><span class="p">,</span> <span class="n">seen_path</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Returns True if a link or its time-shifted version is already</span>
<span class="sd">            included in seen_links.&quot;&quot;&quot;</span>
            <span class="n">i</span><span class="p">,</span> <span class="n">taui</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span><span class="p">,</span> <span class="n">tauj</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

            <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">seen_link</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">seen_path</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]):</span>
                <span class="n">seen_i</span><span class="p">,</span> <span class="n">seen_taui</span> <span class="o">=</span> <span class="n">seen_link</span>
                <span class="n">seen_j</span><span class="p">,</span> <span class="n">seen_tauj</span> <span class="o">=</span> <span class="n">seen_path</span><span class="p">[</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>

                <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">seen_i</span> <span class="ow">and</span> <span class="n">j</span> <span class="o">==</span> <span class="n">seen_j</span>
                    <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tauj</span><span class="o">-</span><span class="n">taui</span><span class="p">)</span> <span class="o">==</span> <span class="nb">abs</span><span class="p">(</span><span class="n">seen_tauj</span><span class="o">-</span><span class="n">seen_taui</span><span class="p">)):</span>
                    <span class="k">return</span> <span class="kc">True</span>

            <span class="k">return</span> <span class="kc">False</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>

        <span class="c1"># Initialize max. ancestral time lag for every N</span>
        <span class="n">max_lag</span> <span class="o">=</span> <span class="mi">0</span>
    
        <span class="c1"># Not sure whether this is relevant!</span>
        <span class="c1"># if self.selection_vars is not None:</span>
        <span class="c1">#     for selection_var in self.selection_vars:</span>
        <span class="c1">#         # print (selection_var, conds)</span>
        <span class="c1">#         # print([(selection_var, -tau_sel) for tau_sel in range(0, max_lag + 1)])</span>
        <span class="c1">#         conds += [(selection_var, -tau_sel) for tau_sel in range(0, max_lag + 1)]</span>

        <span class="c1"># ancestors = dict([(y, []) for y in Y])</span>

        <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">XYZ</span><span class="p">:</span>
            <span class="n">j</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">y</span>   <span class="c1"># tau &lt;= 0</span>
            <span class="n">max_lag</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">max_lag</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))</span>
                
            <span class="n">causal_path</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="n">queue</span> <span class="o">=</span> <span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="n">causal_path</span><span class="p">)]</span>

            <span class="k">while</span> <span class="n">queue</span><span class="p">:</span>
                <span class="n">varlag</span><span class="p">,</span> <span class="n">causal_path</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
                <span class="n">causal_path</span> <span class="o">=</span> <span class="p">[</span><span class="n">varlag</span><span class="p">]</span> <span class="o">+</span> <span class="n">causal_path</span>

                <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_lagged_parents</span><span class="p">(</span><span class="n">varlag</span><span class="p">):</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">node</span>

                    <span class="k">if</span> <span class="p">(</span><span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">causal_path</span><span class="p">):</span>
                    
                        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">causal_path</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">node</span><span class="p">,</span> <span class="n">causal_path</span><span class="p">))</span>
                            <span class="k">continue</span>

                        <span class="k">if</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">causal_path</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_repeating</span><span class="p">((</span><span class="n">node</span><span class="p">,</span> <span class="n">varlag</span><span class="p">),</span> <span class="n">causal_path</span><span class="p">):</span>
                            
                                <span class="n">max_lag</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">max_lag</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))</span>
                                <span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">node</span><span class="p">,</span> <span class="n">causal_path</span><span class="p">))</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Max. non-repeated ancestral time lag: &quot;</span><span class="p">,</span> <span class="n">max_lag</span><span class="p">)</span>

        <span class="c1"># ATTENTION: this may not find correct common ancestors, therefore multiply by 10</span>
        <span class="c1"># until the problem is solved</span>
        <span class="n">max_lag</span> <span class="o">*=</span> <span class="mi">10</span>

        <span class="k">return</span> <span class="n">max_lag</span>

    <span class="k">def</span> <span class="nf">_get_descendants</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">W</span><span class="p">,</span> <span class="n">children</span><span class="p">,</span> <span class="n">max_lag</span><span class="p">,</span> <span class="n">ignore_time_bounds</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Get descendants of nodes in W up to time t.</span>
<span class="sd">        </span>
<span class="sd">        Includes the nodes themselves.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">descendants</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">W</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">W</span><span class="p">:</span>
            <span class="n">j</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">w</span> 
            <span class="n">this_level</span> <span class="o">=</span> <span class="p">[</span><span class="n">w</span><span class="p">]</span>
            <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">next_level</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">varlag</span> <span class="ow">in</span> <span class="n">this_level</span><span class="p">:</span>
                    <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_lagged_children</span><span class="p">(</span><span class="n">varlag</span><span class="p">,</span> <span class="n">children</span><span class="p">):</span>
                        <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">child</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">child</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">descendants</span> 
                            <span class="ow">and</span> <span class="p">(</span><span class="o">-</span><span class="n">max_lag</span> <span class="o">&lt;=</span> <span class="n">tau</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">ignore_time_bounds</span><span class="p">)):</span>
                            <span class="n">descendants</span> <span class="o">=</span> <span class="n">descendants</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="n">child</span><span class="p">]))</span>
                            <span class="n">next_level</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">child</span><span class="p">)</span>

                <span class="n">this_level</span> <span class="o">=</span> <span class="n">next_level</span>       

        <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">descendants</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_has_any_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">conds</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
        <span class="n">starts_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ends_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
        <span class="n">directed</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
        <span class="n">forbidden_nodes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
        <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
        <span class="n">check_optimality_cond</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
        <span class="n">optimality_cond_des_YM</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
        <span class="n">optimality_cond_Y</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
        <span class="n">only_collider_paths_with_vancs</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
        <span class="n">XYS</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
        <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns True if X and Y are d-connected by any open path.</span>

<span class="sd">        Does breadth-first search from both X and Y and meets in the middle.</span>
<span class="sd">        Paths are walked according to the d-separation rules where paths can</span>
<span class="sd">        only traverse motifs &lt;-- v &lt;-- or &lt;-- v --&gt; or --&gt; v --&gt; or</span>
<span class="sd">        --&gt; [v] &lt;-- where [.] indicates that v is conditioned on.</span>
<span class="sd">        Furthermore, paths nodes (v, t) need to fulfill max_lag &lt;= t &lt;= 0</span>
<span class="sd">        and links cannot be traversed backwards.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y : lists of tuples</span>
<span class="sd">            Of the form [(var, -tau)], where var specifies the variable</span>
<span class="sd">            index and tau the time lag.</span>
<span class="sd">        conds : list of tuples</span>
<span class="sd">            Of the form [(var, -tau)], where var specifies the variable</span>
<span class="sd">            index and tau the time lag.</span>
<span class="sd">        max_lag : int</span>
<span class="sd">            Maximum time lag.</span>
<span class="sd">        starts_with : {None, &#39;tail&#39;, &#39;arrohead&#39;}</span>
<span class="sd">            Whether to only consider paths starting with particular mark at X.</span>
<span class="sd">        ends_with : {None, &#39;tail&#39;, &#39;arrohead&#39;}</span>
<span class="sd">            Whether to only consider paths ending with particular mark at Y.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">max_lag</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">conds</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">conds</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="n">max_lag</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_maximum_possible_lag</span><span class="p">(</span><span class="n">X</span><span class="o">+</span><span class="n">Y</span><span class="o">+</span><span class="n">conds</span><span class="p">)</span>

        <span class="k">def</span> <span class="nf">_walk_to_parents</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Helper function to update paths when walking to parents.&quot;&quot;&quot;</span>
            <span class="n">found_connection</span> <span class="o">=</span> <span class="kc">False</span>
            <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_lagged_parents</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> 
                <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="n">only_non_causal_paths</span><span class="p">,</span> <span class="n">X</span><span class="o">=</span><span class="n">X</span><span class="p">,</span> 
                <span class="n">causal_children</span><span class="o">=</span><span class="n">causal_children</span><span class="p">):</span>
                <span class="c1"># Cannot walk into conditioned parents and</span>
                <span class="c1"># cannot walk beyond t or max_lag</span>
                <span class="n">i</span><span class="p">,</span> <span class="n">t</span> <span class="o">=</span> <span class="n">w</span>

                <span class="k">if</span> <span class="n">w</span> <span class="o">==</span> <span class="n">x</span> <span class="ow">and</span> <span class="n">starts_with</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="n">w</span> <span class="o">==</span> <span class="n">y</span> <span class="ow">and</span> <span class="n">ends_with</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="p">(</span><span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">conds</span> <span class="ow">and</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">forbidden_nodes</span> <span class="ow">and</span>
                    <span class="c1"># (w, v) not in seen_links and</span>
                    <span class="n">t</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">max_lag</span><span class="p">):</span>
                    <span class="c1"># if ((w, &#39;tail&#39;) not in this_path and </span>
                    <span class="c1">#     (w, None) not in this_path):</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span> <span class="ow">or</span> 
                        <span class="p">(</span><span class="s1">&#39;tail&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="ow">and</span> <span class="kc">None</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">])):</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Walk parent: </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">  &quot;</span> <span class="o">%</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">w</span><span class="p">))</span>
                        <span class="n">fringe</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">w</span><span class="p">,</span> <span class="s1">&#39;tail&#39;</span><span class="p">))</span>
                        <span class="k">if</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">:</span>
                            <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;tail&#39;</span> <span class="p">:</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">)}</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">][</span><span class="s1">&#39;tail&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">)</span>
                        <span class="c1"># seen_links.append((v, w))</span>
                    <span class="c1"># Determine whether X and Y are connected</span>
                    <span class="c1"># (w, None) indicates the start or end node X/Y</span>
                    <span class="c1"># if ((w, &#39;tail&#39;) in other_path </span>
                    <span class="c1">#    or (w, &#39;arrowhead&#39;) in other_path</span>
                    <span class="c1">#    or (w, None) in other_path):</span>
                    <span class="k">if</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">other_path</span><span class="p">:</span>
                        <span class="n">found_connection</span> <span class="o">=</span> <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="s1">&#39;tail&#39;</span><span class="p">)</span> 
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Found connection: &quot;</span><span class="p">,</span> <span class="n">found_connection</span><span class="p">)</span>  
                        <span class="k">break</span>
            <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span>

        <span class="k">def</span> <span class="nf">_walk_to_children</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Helper function to update paths when walking to children.&quot;&quot;&quot;</span>
            <span class="n">found_connection</span> <span class="o">=</span> <span class="kc">False</span>
            <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_lagged_children</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">children</span><span class="p">,</span> 
                <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="n">only_non_causal_paths</span><span class="p">,</span> <span class="n">X</span><span class="o">=</span><span class="n">X</span><span class="p">,</span> 
                <span class="n">causal_children</span><span class="o">=</span><span class="n">causal_children</span><span class="p">):</span>
                <span class="c1"># You can also walk into conditioned children,</span>
                <span class="c1"># but cannot walk beyond t or max_lag</span>
                <span class="n">i</span><span class="p">,</span> <span class="n">t</span> <span class="o">=</span> <span class="n">w</span>

                <span class="k">if</span> <span class="n">w</span> <span class="o">==</span> <span class="n">x</span> <span class="ow">and</span> <span class="n">starts_with</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="n">w</span> <span class="o">==</span> <span class="n">y</span> <span class="ow">and</span> <span class="n">ends_with</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="p">(</span><span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">forbidden_nodes</span> <span class="ow">and</span>
                    <span class="c1"># (w, v) not in seen_links and</span>
                    <span class="n">t</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">max_lag</span><span class="p">):</span>
                    <span class="c1"># if ((w, &#39;arrowhead&#39;) not in this_path and </span>
                    <span class="c1">#     (w, None) not in this_path):</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span> <span class="ow">or</span> 
                        <span class="p">(</span><span class="s1">&#39;arrowhead&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="ow">and</span> <span class="kc">None</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">])):</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Walk child:  </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">  &quot;</span> <span class="o">%</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">w</span><span class="p">))</span>
                        <span class="n">fringe</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">w</span><span class="p">,</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">))</span>
                        <span class="c1"># this_path[(w, &#39;arrowhead&#39;)] = (v, &#39;tail&#39;)</span>
                        <span class="k">if</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">this_path</span><span class="p">:</span>
                            <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;arrowhead&#39;</span> <span class="p">:</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s1">&#39;tail&#39;</span><span class="p">)}</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="n">this_path</span><span class="p">[</span><span class="n">w</span><span class="p">][</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s1">&#39;tail&#39;</span><span class="p">)</span>
                        <span class="c1"># seen_links.append((v, w))</span>
                    <span class="c1"># Determine whether X and Y are connected</span>
                    <span class="c1"># If the other_path contains w with a tail, then w must</span>
                    <span class="c1"># NOT be conditioned on. Alternatively, if the other_path</span>
                    <span class="c1"># contains w with an arrowhead, then w must be</span>
                    <span class="c1"># conditioned on.</span>
                    <span class="c1"># if (((w, &#39;tail&#39;) in other_path and w not in conds)</span>
                    <span class="c1">#    or ((w, &#39;arrowhead&#39;) in other_path and w in conds)</span>
                    <span class="c1">#    or (w, None) in other_path):</span>
                    <span class="k">if</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">other_path</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">((</span><span class="s1">&#39;tail&#39;</span> <span class="ow">in</span> <span class="n">other_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="ow">and</span> <span class="n">w</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">)</span> <span class="ow">or</span>
                            <span class="p">(</span><span class="s1">&#39;arrowhead&#39;</span> <span class="ow">in</span> <span class="n">other_path</span><span class="p">[</span><span class="n">w</span><span class="p">]</span> <span class="ow">and</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">)</span> <span class="ow">or</span>
                            <span class="p">(</span><span class="kc">None</span> <span class="ow">in</span> <span class="n">other_path</span><span class="p">[</span><span class="n">w</span><span class="p">])):</span>
                            <span class="n">found_connection</span> <span class="o">=</span> <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">)</span> 
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Found connection: &quot;</span><span class="p">,</span> <span class="n">found_connection</span><span class="p">)</span> 
                            <span class="k">break</span>
            <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span>

        <span class="k">def</span> <span class="nf">_walk_fringe</span><span class="p">(</span><span class="n">this_level</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Helper function to walk each fringe, i.e., the path from X and Y,</span>
<span class="sd">            respectively.&quot;&quot;&quot;</span>
            <span class="n">found_connection</span> <span class="o">=</span> <span class="kc">False</span>

            <span class="k">if</span> <span class="n">starts_with</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">this_level</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_parents</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span>

            <span class="k">elif</span> <span class="n">starts_with</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">this_level</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_children</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span> 

            <span class="k">if</span> <span class="n">ends_with</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">this_level</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_parents</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span>

            <span class="k">elif</span> <span class="n">ends_with</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">this_level</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">this_level</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_children</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span> 

            <span class="k">for</span> <span class="n">v</span><span class="p">,</span> <span class="n">mark</span> <span class="ow">in</span> <span class="n">this_level</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">mark</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span> <span class="ow">or</span> <span class="n">mark</span> <span class="o">==</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">and</span> <span class="n">directed</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
                        <span class="c1"># Motif: --&gt; [v] &lt;--</span>
                        <span class="c1"># If standing on a condition and coming from an</span>
                        <span class="c1"># arrowhead, you can only walk into parents</span>
                        <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_parents</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                        <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> <span class="k">break</span>            
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">only_collider_paths_with_vancs</span><span class="p">:</span>
                        <span class="k">continue</span>

                    <span class="k">if</span> <span class="p">(</span><span class="n">mark</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span> <span class="ow">or</span> <span class="n">mark</span> <span class="o">==</span> <span class="kc">None</span><span class="p">):</span>
                        <span class="c1"># Motif: &lt;-- v &lt;-- or &lt;-- v --&gt;</span>
                        <span class="c1"># If NOT standing on a condition and coming from</span>
                        <span class="c1"># a tail mark, you can walk into parents or </span>
                        <span class="c1"># children</span>
                        <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_parents</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                        <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> <span class="k">break</span> 
                        
                        <span class="k">if</span> <span class="ow">not</span> <span class="n">directed</span><span class="p">:</span>
                            <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                             <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_children</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                           <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                            <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> <span class="k">break</span> 
                      
                    <span class="k">elif</span> <span class="n">mark</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                        <span class="c1"># Motif: --&gt; v --&gt;</span>
                        <span class="c1"># If NOT standing on a condition and coming from</span>
                        <span class="c1"># an arrowhead mark, you can only walk into</span>
                        <span class="c1"># children</span>
                        <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                         <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_children</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                       <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                        <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> <span class="k">break</span>

                        <span class="k">if</span> <span class="n">check_optimality_cond</span> <span class="ow">and</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">:</span>
                            <span class="c1"># if v is not descendant of YM</span>
                            <span class="c1"># and v is not connected to Y given X OS\Cu</span>
                            <span class="c1"># print(&quot;v = &quot;, v)</span>
                            <span class="n">cond4a</span> <span class="o">=</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">optimality_cond_des_YM</span>
                            <span class="n">cond4b</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[</span><span class="n">v</span><span class="p">],</span> <span class="n">Y</span><span class="o">=</span><span class="n">optimality_cond_Y</span><span class="p">,</span> 
                                <span class="n">conds</span><span class="o">=</span><span class="n">conds</span> <span class="o">+</span> <span class="n">X</span><span class="p">,</span> 
                                <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                                <span class="n">starts_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">ends_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>  
                                <span class="n">forbidden_nodes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="c1">#list(prelim_Oset), </span>
                                <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
                            <span class="c1"># print(cond4a, cond4b)</span>
                            <span class="k">if</span> <span class="n">cond4a</span> <span class="ow">and</span> <span class="n">cond4b</span><span class="p">:</span>
                                <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span>
                                 <span class="n">this_path</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_to_parents</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> 
                                                               <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span><span class="p">)</span>
                                <span class="c1"># print(found_connection)</span>
                                <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> <span class="k">break</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Updated fringe: &quot;</span><span class="p">,</span> <span class="n">fringe</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">found_connection</span><span class="p">,</span> <span class="n">fringe</span><span class="p">,</span> <span class="n">this_path</span><span class="p">,</span> <span class="n">other_path</span>

        <span class="k">def</span> <span class="nf">backtrace_path</span><span class="p">():</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Helper function to get path from start point, end point, </span>
<span class="sd">            and connection found.&quot;&quot;&quot;</span>

            <span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">found_connection</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
            <span class="n">node</span><span class="p">,</span> <span class="n">mark</span> <span class="o">=</span> <span class="n">found_connection</span>

            <span class="k">if</span> <span class="s1">&#39;tail&#39;</span> <span class="ow">in</span> <span class="n">pred</span><span class="p">[</span><span class="n">node</span><span class="p">]:</span>
                <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span>
            <span class="c1"># print(found_connection)</span>
            <span class="k">while</span> <span class="n">path</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="n">x</span><span class="p">:</span>
                <span class="c1"># print(path, node, mark, pred[node])</span>
                <span class="n">prev_node</span><span class="p">,</span> <span class="n">prev_mark</span> <span class="o">=</span> <span class="n">pred</span><span class="p">[</span><span class="n">node</span><span class="p">][</span><span class="n">mark</span><span class="p">]</span>
                <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">prev_node</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">prev_mark</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">prev_node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
                        <span class="c1"># if pass_through_colliders:</span>
                        <span class="c1">#     if &#39;tail&#39; in pred[prev_node] and pred[prev_node][&#39;tail&#39;] != (node, mark):</span>
                        <span class="c1">#         mark = &#39;tail&#39;</span>
                        <span class="c1">#     else:</span>
                        <span class="c1">#         mark = &#39;arrowhead&#39;</span>
                        <span class="c1"># else:</span>
                            <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
                    <span class="k">elif</span> <span class="n">prev_node</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span>
                <span class="k">elif</span> <span class="n">prev_mark</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                    <span class="k">if</span> <span class="s1">&#39;tail&#39;</span> <span class="ow">in</span> <span class="n">pred</span><span class="p">[</span><span class="n">prev_node</span><span class="p">]</span> <span class="ow">and</span> <span class="n">pred</span><span class="p">[</span><span class="n">prev_node</span><span class="p">][</span><span class="s1">&#39;tail&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">mark</span><span class="p">):</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span> 
                <span class="n">node</span> <span class="o">=</span> <span class="n">prev_node</span>

            <span class="n">path</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span>

            <span class="n">node</span><span class="p">,</span> <span class="n">mark</span> <span class="o">=</span> <span class="n">found_connection</span>
            <span class="k">if</span> <span class="s1">&#39;tail&#39;</span> <span class="ow">in</span> <span class="n">succ</span><span class="p">[</span><span class="n">node</span><span class="p">]:</span>
                <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span>

            <span class="k">while</span> <span class="n">path</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="n">y</span><span class="p">:</span>
                <span class="n">next_node</span><span class="p">,</span> <span class="n">next_mark</span> <span class="o">=</span> <span class="n">succ</span><span class="p">[</span><span class="n">node</span><span class="p">][</span><span class="n">mark</span><span class="p">]</span>
                <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">next_node</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">next_mark</span> <span class="o">==</span> <span class="s1">&#39;arrowhead&#39;</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">next_node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
                        <span class="c1"># if pass_through_colliders:</span>
                        <span class="c1">#     if &#39;tail&#39; in succ[next_node] and succ[next_node][&#39;tail&#39;] != (node, mark):</span>
                        <span class="c1">#         mark = &#39;tail&#39;</span>
                        <span class="c1">#     else:</span>
                        <span class="c1">#         mark = &#39;arrowhead&#39;</span>
                        <span class="c1"># else:</span>
                            <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
                    <span class="k">elif</span> <span class="n">next_node</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span>
                <span class="k">elif</span> <span class="n">next_mark</span> <span class="o">==</span> <span class="s1">&#39;tail&#39;</span><span class="p">:</span>
                    <span class="k">if</span> <span class="s1">&#39;tail&#39;</span> <span class="ow">in</span> <span class="n">succ</span><span class="p">[</span><span class="n">next_node</span><span class="p">]</span> <span class="ow">and</span> <span class="n">succ</span><span class="p">[</span><span class="n">next_node</span><span class="p">][</span><span class="s1">&#39;tail&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">mark</span><span class="p">):</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;tail&#39;</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">mark</span> <span class="o">=</span> <span class="s1">&#39;arrowhead&#39;</span> 
                <span class="n">node</span> <span class="o">=</span> <span class="n">next_node</span>

            <span class="k">return</span> <span class="n">path</span>


        <span class="k">if</span> <span class="n">conds</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">conds</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="k">if</span> <span class="n">forbidden_nodes</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">forbidden_nodes</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="n">conds</span> <span class="o">=</span> <span class="p">[</span><span class="n">z</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">conds</span> <span class="k">if</span> <span class="n">z</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Y</span> <span class="ow">and</span> <span class="n">z</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">X</span><span class="p">]</span>
        <span class="c1"># print(X, Y, conds)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">selection_var</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">:</span>
                <span class="n">conds</span> <span class="o">+=</span> <span class="p">[(</span><span class="n">selection_var</span><span class="p">,</span> <span class="o">-</span><span class="n">tau_sel</span><span class="p">)</span> <span class="k">for</span> <span class="n">tau_sel</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">max_lag</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>


        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>
        <span class="n">children</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_children</span><span class="p">()</span>

        <span class="k">if</span> <span class="n">only_non_causal_paths</span><span class="p">:</span>
            <span class="n">anc_Y_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_non_blocked_ancestors</span><span class="p">(</span><span class="n">Y</span><span class="o">=</span><span class="n">Y</span><span class="p">,</span> <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;max_lag&#39;</span><span class="p">,</span>
                                    <span class="n">max_lag</span><span class="o">=</span><span class="n">max_lag</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
            <span class="c1"># print(anc_Y_dict)</span>
            <span class="n">anc_Y</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">:</span>
                <span class="n">anc_Y</span> <span class="o">+=</span> <span class="n">anc_Y_dict</span><span class="p">[</span><span class="n">y</span><span class="p">]</span>
            <span class="n">des_X</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_descendants</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">children</span><span class="o">=</span><span class="n">children</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="n">max_lag</span><span class="p">)</span>
            <span class="n">mediators</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">anc_Y</span><span class="p">)</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">des_X</span><span class="p">))</span> <span class="o">-</span> <span class="nb">set</span><span class="p">(</span><span class="n">Y</span><span class="p">)</span> <span class="o">-</span> <span class="nb">set</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>

            <span class="n">causal_children</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">mediators</span><span class="p">)</span> <span class="o">+</span> <span class="n">Y</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">causal_children</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="k">if</span> <span class="n">only_collider_paths_with_vancs</span><span class="p">:</span>
            <span class="n">vancs_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_non_blocked_ancestors</span><span class="p">(</span><span class="n">Y</span><span class="o">=</span><span class="n">XYS</span><span class="p">,</span> <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;max_lag&#39;</span><span class="p">,</span>
                                    <span class="n">max_lag</span><span class="o">=</span><span class="n">max_lag</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">vancs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
            <span class="k">for</span> <span class="n">xys</span> <span class="ow">in</span> <span class="n">XYS</span><span class="p">:</span>
                <span class="n">vancs</span> <span class="o">=</span> <span class="n">vancs</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">vancs_dict</span><span class="p">[</span><span class="n">xys</span><span class="p">]))</span>
            <span class="n">vancs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">vancs</span><span class="p">)</span> <span class="o">+</span> <span class="n">XYS</span>
            <span class="n">conds</span> <span class="o">=</span> <span class="n">vancs</span>
        <span class="c1"># else:</span>
        <span class="c1">#     vancs = None</span>

        <span class="c1"># Iterate through nodes in X and Y</span>
        <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">X</span><span class="p">:</span>
          <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">:</span>

            <span class="c1"># seen_links = []</span>
            <span class="c1"># predecessor and successors in search</span>
            <span class="c1"># (x, None) where None indicates start/end nodes, later (v,</span>
            <span class="c1"># &#39;tail&#39;) or (w, &#39;arrowhead&#39;) indicate how a link ends at a node</span>
            <span class="n">pred</span> <span class="o">=</span> <span class="p">{</span><span class="n">x</span> <span class="p">:</span> <span class="p">{</span><span class="kc">None</span><span class="p">:</span> <span class="kc">None</span><span class="p">}}</span>
            <span class="n">succ</span> <span class="o">=</span> <span class="p">{</span><span class="n">y</span> <span class="p">:</span> <span class="p">{</span><span class="kc">None</span><span class="p">:</span> <span class="kc">None</span><span class="p">}}</span>

            <span class="c1"># initialize fringes, start with forward from X</span>
            <span class="n">forward_fringe</span> <span class="o">=</span> <span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="kc">None</span><span class="p">)]</span>
            <span class="n">reverse_fringe</span> <span class="o">=</span> <span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="kc">None</span><span class="p">)]</span>

            <span class="k">while</span> <span class="n">forward_fringe</span> <span class="ow">and</span> <span class="n">reverse_fringe</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">forward_fringe</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">reverse_fringe</span><span class="p">):</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Walk from X since len(X_fringe)=</span><span class="si">%d</span><span class="s2"> &quot;</span>
                              <span class="s2">&quot;&lt;= len(Y_fringe)=</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">forward_fringe</span><span class="p">),</span> 
                                <span class="nb">len</span><span class="p">(</span><span class="n">reverse_fringe</span><span class="p">)))</span>
                    <span class="n">this_level</span> <span class="o">=</span> <span class="n">forward_fringe</span>
                    <span class="n">forward_fringe</span> <span class="o">=</span> <span class="p">[]</span>    
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">forward_fringe</span><span class="p">,</span> <span class="n">pred</span><span class="p">,</span> 
                     <span class="n">succ</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_fringe</span><span class="p">(</span><span class="n">this_level</span><span class="p">,</span> <span class="n">forward_fringe</span><span class="p">,</span> <span class="n">pred</span><span class="p">,</span> 
                                                <span class="n">succ</span><span class="p">)</span>

                    <span class="c1"># print(pred)</span>
                    <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> 
                        <span class="k">if</span> <span class="n">return_path</span><span class="p">:</span>
                            <span class="n">backtraced_path</span> <span class="o">=</span> <span class="n">backtrace_path</span><span class="p">()</span>
                            <span class="k">return</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">node</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> 
                                    <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">backtraced_path</span> 
                                    <span class="k">if</span> <span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>
                        <span class="k">else</span><span class="p">:</span> 
                            <span class="k">return</span> <span class="kc">True</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Walk from Y since len(X_fringe)=</span><span class="si">%d</span><span class="s2"> &quot;</span>
                              <span class="s2">&quot;&gt; len(Y_fringe)=</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">forward_fringe</span><span class="p">),</span> 
                                <span class="nb">len</span><span class="p">(</span><span class="n">reverse_fringe</span><span class="p">)))</span>
                    <span class="n">this_level</span> <span class="o">=</span> <span class="n">reverse_fringe</span>
                    <span class="n">reverse_fringe</span> <span class="o">=</span> <span class="p">[]</span>
                    <span class="p">(</span><span class="n">found_connection</span><span class="p">,</span> <span class="n">reverse_fringe</span><span class="p">,</span> <span class="n">succ</span><span class="p">,</span> 
                     <span class="n">pred</span><span class="p">)</span> <span class="o">=</span> <span class="n">_walk_fringe</span><span class="p">(</span><span class="n">this_level</span><span class="p">,</span> <span class="n">reverse_fringe</span><span class="p">,</span> <span class="n">succ</span><span class="p">,</span> 
                                                <span class="n">pred</span><span class="p">)</span>

                    <span class="k">if</span> <span class="n">found_connection</span><span class="p">:</span> 
                        <span class="k">if</span> <span class="n">return_path</span><span class="p">:</span>
                            <span class="n">backtraced_path</span> <span class="o">=</span> <span class="n">backtrace_path</span><span class="p">()</span>
                            <span class="k">return</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">node</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> 
                                    <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">backtraced_path</span> 
                                    <span class="k">if</span> <span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>
                        <span class="k">else</span><span class="p">:</span> 
                            <span class="k">return</span> <span class="kc">True</span>

                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;X_fringe = </span><span class="si">%s</span><span class="s2"> </span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">forward_fringe</span><span class="p">)</span> <span class="o">+</span>
                          <span class="s2">&quot;Y_fringe = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">reverse_fringe</span><span class="p">))</span>           

        <span class="k">return</span> <span class="kc">False</span>

    <span class="k">def</span> <span class="nf">_is_dsep</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns whether X and Y are d-separated given Z in the graph.</span>

<span class="sd">        X, Y, Z are of the form (var, lag) for lag &lt;= 0. D-separation is</span>
<span class="sd">        based on:</span>

<span class="sd">        1. Assessing the maximum time lag max_lag possible for any confounding</span>
<span class="sd">        path (see _get_maximum_possible_lag(...)).</span>

<span class="sd">        2. Using the time series graph truncated at max_lag we then test</span>
<span class="sd">        d-separation between X and Y conditional on Z using breadth-first</span>
<span class="sd">        search of non-blocked paths according to d-separation rules.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y, Z : list of tuples</span>
<span class="sd">            List of variables chosen for current independence test.</span>
<span class="sd">        max_lag : int, optional (default: None)</span>
<span class="sd">            Used here to constrain the _is_dsep function to the graph</span>
<span class="sd">            truncated at max_lag instead of identifying the max_lag from</span>
<span class="sd">            ancestral search.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        dseparated : bool, or path</span>
<span class="sd">            True if X and Y are d-separated given Z in the graph.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Testing X=</span><span class="si">%s</span><span class="s2"> d-sep Y=</span><span class="si">%s</span><span class="s2"> given Z=</span><span class="si">%s</span><span class="s2"> in TSG&quot;</span> <span class="o">%</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))</span>

        <span class="k">if</span> <span class="n">Z</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">Z</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="k">if</span> <span class="n">max_lag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># max_lags = dict([(j, max_lag) for j in range(N)])</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Set max. time lag to: &quot;</span><span class="p">,</span> <span class="n">max_lag</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">max_lag</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_maximum_possible_lag</span><span class="p">(</span><span class="n">X</span><span class="o">+</span><span class="n">Y</span><span class="o">+</span><span class="n">Z</span><span class="p">)</span>

        <span class="c1"># Store overall max. lag</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max_lag</span> <span class="o">=</span> <span class="n">max_lag</span>

        <span class="c1"># _has_any_path is the main function that searches open paths</span>
        <span class="n">any_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">conds</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="n">max_lag</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">any_path</span><span class="p">:</span>
            <span class="n">dseparated</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">dseparated</span> <span class="o">=</span> <span class="kc">True</span>

        <span class="k">return</span> <span class="n">dseparated</span>

<div class="viewcode-block" id="OracleCI.check_shortest_path"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.check_shortest_path">[docs]</a>    <span class="k">def</span> <span class="nf">check_shortest_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span>
                 <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>  <span class="c1"># compute_ancestors=False, </span>
                 <span class="n">starts_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ends_with</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                 <span class="n">forbidden_nodes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">directed</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                 <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                 <span class="n">check_optimality_cond</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                 <span class="n">optimality_cond_des_YM</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">optimality_cond_Y</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns path between X and Y given Z in the graph.</span>

<span class="sd">        X, Y, Z are of the form (var, lag) for lag &lt;= 0. D-separation is</span>
<span class="sd">        based on:</span>

<span class="sd">        1. Assessing maximum time lag max_lag of last ancestor of any X, Y, Z</span>
<span class="sd">        with non-blocked (by Z), non-repeating directed path towards X, Y, Z</span>
<span class="sd">        in the graph. &#39;non_repeating&#39; means that an ancestor X^i_{ t-\tau_i}</span>
<span class="sd">        with link X^i_{t-\tau_i} --&gt; X^j_{ t-\tau_j} is only included if</span>
<span class="sd">        X^i_{t&#39;-\tau_i} --&gt; X^j_{ t&#39;-\tau_j} for t&#39;!=t is not already part of</span>
<span class="sd">        the ancestors.</span>

<span class="sd">        2. Using the time series graph truncated at max_lag we then test</span>
<span class="sd">        d-separation between X and Y conditional on Z using breadth-first</span>
<span class="sd">        search of non-blocked paths according to d-separation rules including</span>
<span class="sd">        selection variables.</span>

<span class="sd">        Optionally only considers paths starting/ending with specific marks)</span>
<span class="sd">        and makes available the ancestors up to max_lag of X, Y, Z. This may take </span>
<span class="sd">        a very long time, however.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y, Z : list of tuples</span>
<span class="sd">            List of variables chosen for testing paths.</span>
<span class="sd">        max_lag : int, optional (default: None)</span>
<span class="sd">            Used here to constrain the has_path function to the graph</span>
<span class="sd">            truncated at max_lag instead of identifying the max_lag from</span>
<span class="sd">            ancestral search.</span>
<span class="sd">        compute_ancestors : bool</span>
<span class="sd">            Whether to also make available the ancestors for X, Y, Z as</span>
<span class="sd">            self.anc_all_x, self.anc_all_y, and self.anc_all_z, respectively.</span>
<span class="sd">        starts_with : {None, &#39;tail&#39;, &#39;arrohead&#39;}</span>
<span class="sd">            Whether to only consider paths starting with particular mark at X.</span>
<span class="sd">        ends_with : {None, &#39;tail&#39;, &#39;arrohead&#39;}</span>
<span class="sd">            Whether to only consider paths ending with particular mark at Y.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        path : list or False</span>
<span class="sd">            Returns path or False if no path exists.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>

        <span class="c1"># Translate from observed_vars index to full variable set index</span>
        <span class="n">X</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">X</span><span class="p">]</span>
        <span class="n">Y</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">]</span>
        <span class="n">Z</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">z</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">z</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>

        <span class="c1"># print(X)</span>
        <span class="c1"># print(Y)</span>
        <span class="c1"># print(Z)</span>

        <span class="k">if</span> <span class="n">check_optimality_cond</span><span class="p">:</span>
            <span class="n">optimality_cond_des_YM</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> 
                                        <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">optimality_cond_des_YM</span><span class="p">]</span>
            <span class="n">optimality_cond_Y</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> 
                                    <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">optimality_cond_Y</span><span class="p">]</span>

        <span class="c1"># Get the array to test on</span>
        <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_XYZ</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Testing X=</span><span class="si">%s</span><span class="s2"> d-sep Y=</span><span class="si">%s</span><span class="s2"> given Z=</span><span class="si">%s</span><span class="s2"> in TSG&quot;</span> <span class="o">%</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))</span>

        <span class="k">if</span> <span class="n">max_lag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># max_lags = dict([(j, max_lag) for j in range(N)])</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Set max. time lag to: &quot;</span><span class="p">,</span> <span class="n">max_lag</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">max_lag</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_maximum_possible_lag</span><span class="p">(</span><span class="n">X</span><span class="o">+</span><span class="n">Y</span><span class="o">+</span><span class="n">Z</span><span class="p">)</span>

        <span class="c1"># Store overall max. lag</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max_lag</span> <span class="o">=</span> <span class="n">max_lag</span>

        <span class="c1"># _has_any_path is the main function that searches open paths</span>
        <span class="n">any_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">conds</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="n">max_lag</span><span class="p">,</span> 
                                      <span class="n">starts_with</span><span class="o">=</span><span class="n">starts_with</span><span class="p">,</span> <span class="n">ends_with</span><span class="o">=</span><span class="n">ends_with</span><span class="p">,</span>
                                      <span class="n">return_path</span><span class="o">=</span><span class="n">return_path</span><span class="p">,</span>
                                      <span class="n">directed</span><span class="o">=</span><span class="n">directed</span><span class="p">,</span>
                                      <span class="n">only_non_causal_paths</span><span class="o">=</span><span class="n">only_non_causal_paths</span><span class="p">,</span>
                                      <span class="n">check_optimality_cond</span><span class="o">=</span><span class="n">check_optimality_cond</span><span class="p">,</span>
                                      <span class="n">optimality_cond_des_YM</span><span class="o">=</span><span class="n">optimality_cond_des_YM</span><span class="p">,</span>
                                      <span class="n">optimality_cond_Y</span><span class="o">=</span><span class="n">optimality_cond_Y</span><span class="p">,</span>
                                      <span class="n">forbidden_nodes</span><span class="o">=</span><span class="n">forbidden_nodes</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">any_path</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">return_path</span><span class="p">:</span>
                <span class="n">any_path_observed</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">node</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">any_path</span> 
                             <span class="k">if</span> <span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">any_path_observed</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="k">else</span><span class="p">:</span> 
            <span class="n">any_path_observed</span> <span class="o">=</span> <span class="kc">False</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;_has_any_path     = &quot;</span><span class="p">,</span> <span class="n">any_path</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;_has_any_path_obs = &quot;</span><span class="p">,</span> <span class="n">any_path_observed</span><span class="p">)</span>


        <span class="c1"># if compute_ancestors:</span>
        <span class="c1">#     if self.verbosity &gt; 0:</span>
        <span class="c1">#         print(&quot;Compute ancestors.&quot;)</span>

        <span class="c1">#     # Get ancestors up to maximum ancestral time lag incl. repeated</span>
        <span class="c1">#     # links</span>
        <span class="c1">#     self.anc_all_x, _ = self._get_non_blocked_ancestors(X, conds=Z,</span>
        <span class="c1">#                                     mode=&#39;max_lag&#39;, max_lag=max_lag)</span>
        <span class="c1">#     self.anc_all_y, _ = self._get_non_blocked_ancestors(Y, conds=Z,</span>
        <span class="c1">#                                     mode=&#39;max_lag&#39;, max_lag=max_lag)</span>
        <span class="c1">#     self.anc_all_z, _ = self._get_non_blocked_ancestors(Z, conds=Z,</span>
        <span class="c1">#                                     mode=&#39;max_lag&#39;, max_lag=max_lag)</span>

        <span class="k">return</span> <span class="n">any_path_observed</span></div>

<div class="viewcode-block" id="OracleCI.run_test"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.run_test">[docs]</a>    <span class="k">def</span> <span class="nf">run_test</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">cut_off</span><span class="o">=</span><span class="s1">&#39;2xtau_max&#39;</span><span class="p">,</span> <span class="n">alpha_or_thres</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Perform oracle conditional independence test.</span>

<span class="sd">        Calls the d-separation function.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y, Z : list of tuples</span>
<span class="sd">            X,Y,Z are of the form [(var, -tau)], where var specifies the</span>
<span class="sd">            variable index in the observed_vars and tau the time lag.</span>
<span class="sd">        tau_max : int, optional (default: 0)</span>
<span class="sd">            Not used here.</span>
<span class="sd">        cut_off : {&#39;2xtau_max&#39;, &#39;max_lag&#39;, &#39;max_lag_or_tau_max&#39;}</span>
<span class="sd">            Not used here.</span>
<span class="sd">        alpha_or_thres : float</span>
<span class="sd">            Not used here.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        val, pval : Tuple of floats</span>
<span class="sd">            The test statistic value and the p-value.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">Z</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">Z</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="c1"># Translate from observed_vars index to full variable set index</span>
        <span class="n">X</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">X</span><span class="p">]</span>
        <span class="n">Y</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">]</span>
        <span class="n">Z</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">z</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">z</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>

        <span class="c1"># Get the array to test on</span>
        <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_XYZ</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">[</span><span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_dsep</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">[</span><span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))]:</span>
            <span class="n">val</span> <span class="o">=</span> <span class="mf">0.</span>
            <span class="n">pval</span> <span class="o">=</span> <span class="mf">1.</span>
            <span class="n">dependent</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">val</span> <span class="o">=</span> <span class="mf">1.</span>
            <span class="n">pval</span> <span class="o">=</span> <span class="mf">0.</span>
            <span class="n">dependent</span> <span class="o">=</span> <span class="kc">True</span>

        <span class="k">if</span> <span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_cond_ind_results</span><span class="p">(</span><span class="n">val</span><span class="o">=</span><span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="o">=</span><span class="n">pval</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                                         <span class="n">conf</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
        <span class="c1"># Return the value and the pvalue</span>
        <span class="k">if</span> <span class="n">alpha_or_thres</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">val</span><span class="p">,</span> <span class="n">pval</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">dependent</span></div>

<div class="viewcode-block" id="OracleCI.get_measure"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.get_measure">[docs]</a>    <span class="k">def</span> <span class="nf">get_measure</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns dependence measure.</span>

<span class="sd">        Returns 0 if X and Y are d-separated given Z in the graph and 1 else.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        X, Y [, Z] : list of tuples</span>
<span class="sd">            X,Y,Z are of the form [(var, -tau)], where var specifies the</span>
<span class="sd">            variable index in the observed_vars and tau the time lag.</span>

<span class="sd">        tau_max : int, optional (default: 0)</span>
<span class="sd">            Maximum time lag. This may be used to make sure that estimates for</span>
<span class="sd">            different lags in X, Z, all have the same sample size.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        val : float</span>
<span class="sd">            The test statistic value.</span>

<span class="sd">        &quot;&quot;&quot;</span>

        <span class="c1"># Translate from observed_vars index to full variable set index</span>
        <span class="n">X</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">X</span><span class="p">]</span>
        <span class="n">Y</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">Y</span><span class="p">]</span>
        <span class="n">Z</span> <span class="o">=</span> <span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">[</span><span class="n">z</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">z</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>

        <span class="c1"># Check XYZ</span>
        <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span> <span class="o">=</span> <span class="n">_check_XYZ</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">[</span><span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_dsep</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">dsepsets</span><span class="p">[</span><span class="nb">str</span><span class="p">((</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="p">))]:</span>
            <span class="k">return</span> <span class="mf">0.</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="mf">1.</span></div>

    <span class="k">def</span> <span class="nf">_print_cond_ind_results</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">conf</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print results from conditional independence test.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        val : float</span>
<span class="sd">            Test stastistic value.</span>
<span class="sd">        pval : float, optional (default: None)</span>
<span class="sd">            p-value</span>
<span class="sd">        conf : tuple of floats, optional (default: None)</span>
<span class="sd">            Confidence bounds.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">printstr</span> <span class="o">=</span> <span class="s2">&quot;        val = </span><span class="si">%.3f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">val</span><span class="p">)</span>      
        <span class="k">if</span> <span class="n">pval</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">printstr</span> <span class="o">+=</span> <span class="s2">&quot; | pval = </span><span class="si">%.5f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pval</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">conf</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">printstr</span> <span class="o">+=</span> <span class="s2">&quot; | conf bounds = (</span><span class="si">%.3f</span><span class="s2">, </span><span class="si">%.3f</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="n">conf</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">conf</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
        <span class="k">if</span> <span class="n">cached</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">printstr</span> <span class="o">+=</span> <span class="s2">&quot; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">({</span><span class="mi">0</span><span class="p">:</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">:</span><span class="s2">&quot;[cached]&quot;</span><span class="p">}[</span><span class="n">cached</span><span class="p">])</span>

        <span class="nb">print</span><span class="p">(</span><span class="n">printstr</span><span class="p">)</span>

<div class="viewcode-block" id="OracleCI.get_model_selection_criterion"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.get_model_selection_criterion">[docs]</a>    <span class="k">def</span> <span class="nf">get_model_selection_criterion</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">parents</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Base class assumption that this is not implemented.  Concrete classes</span>
<span class="sd">        should override when possible.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s2">&quot;Model selection not&quot;</span><span class="o">+</span>\
                                  <span class="s2">&quot; implemented for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">measure</span><span class="p">)</span></div>

    <span class="k">def</span> <span class="nf">_reverse_patt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">patt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Inverts a link pattern&quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">patt</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
            <span class="k">return</span> <span class="s2">&quot;&quot;</span>

        <span class="n">left_mark</span><span class="p">,</span> <span class="n">middle_mark</span><span class="p">,</span> <span class="n">right_mark</span> <span class="o">=</span> <span class="n">patt</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">patt</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">patt</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
        <span class="k">if</span> <span class="n">left_mark</span> <span class="o">==</span> <span class="s2">&quot;&lt;&quot;</span><span class="p">:</span>
            <span class="n">new_right_mark</span> <span class="o">=</span> <span class="s2">&quot;&gt;&quot;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">new_right_mark</span> <span class="o">=</span> <span class="n">left_mark</span>
        <span class="k">if</span> <span class="n">right_mark</span> <span class="o">==</span> <span class="s2">&quot;&gt;&quot;</span><span class="p">:</span>
            <span class="n">new_left_mark</span> <span class="o">=</span> <span class="s2">&quot;&lt;&quot;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">new_left_mark</span> <span class="o">=</span> <span class="n">right_mark</span>

        <span class="k">return</span> <span class="n">new_left_mark</span> <span class="o">+</span> <span class="n">middle_mark</span> <span class="o">+</span> <span class="n">new_right_mark</span>


<div class="viewcode-block" id="OracleCI.get_links_from_graph"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.get_links_from_graph">[docs]</a>    <span class="k">def</span> <span class="nf">get_links_from_graph</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Constructs links_coeffs dictionary, observed_vars, </span>
<span class="sd">        and selection_vars from graph array (MAG or DAG).</span>

<span class="sd">        In the case of MAGs, for every &lt;-&gt; or --- link further</span>
<span class="sd">        latent and selection variables, respectively, are added.</span>
<span class="sd">        This corresponds to a canonical DAG (Richardson Spirtes 2002).</span>

<span class="sd">        For ADMGs &quot;---&quot; are not supported, but also links of type &quot;+-&gt;&quot;</span>
<span class="sd">        exist, which corresponds to having both &quot;--&gt;&quot; and &quot;&lt;-&gt;&quot;.</span>

<span class="sd">        Can be used to evaluate d-separation in MAG/DAGs.</span>

<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="s2">&quot;U3&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">graph</span><span class="o">.</span><span class="n">dtype</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;graph must be of type &#39;&lt;U3&#39;!&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_is_mag</span><span class="p">:</span>
            <span class="n">edge_types</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;--&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;---&quot;</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">edge_types</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;--&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;+-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;-+&quot;</span><span class="p">]</span> <span class="c1">#, &quot;--+&quot;, &quot;+--&quot;]</span>


        <span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">tau_maxplusone</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span>
        <span class="n">tau_max</span> <span class="o">=</span> <span class="n">tau_maxplusone</span> <span class="o">-</span> <span class="mi">1</span>

        <span class="n">observed_vars</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">))</span>

        <span class="n">selection_vars</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="n">links</span> <span class="o">=</span> <span class="p">{</span><span class="n">j</span><span class="p">:</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">observed_vars</span> <span class="p">}</span>

        <span class="c1"># Add further latent variables to accommodate &lt;-&gt; and --- links</span>
        <span class="n">latent_index</span> <span class="o">=</span> <span class="n">N</span>
        <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">graph</span><span class="p">)):</span>

            <span class="n">edge_type</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span>

            <span class="k">if</span> <span class="n">edge_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">edge_types</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                    <span class="s2">&quot;Links can only be in </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span><span class="nb">str</span><span class="p">(</span><span class="n">edge_types</span><span class="p">)</span>
                <span class="p">)</span>

            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">edge_type</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_reverse_patt</span><span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]):</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;graph needs to have consistent lag-zero patterns (eg&quot;</span>
                        <span class="s2">&quot; graph[i,j,0]=&#39;--&gt;&#39; requires graph[j,i,0]=&#39;&lt;--&#39;)&quot;</span>
                    <span class="p">)</span>

                <span class="c1"># Consider contemporaneous links only once</span>
                <span class="k">if</span> <span class="n">j</span> <span class="o">&gt;</span> <span class="n">i</span><span class="p">:</span>
                    <span class="k">continue</span>

            <span class="c1"># Restrict lagged links</span>
            <span class="k">else</span><span class="p">:</span> 
                <span class="k">if</span> <span class="n">edge_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;--&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;---&quot;</span><span class="p">,</span> <span class="s2">&quot;+-&gt;&quot;</span><span class="p">]:</span> <span class="c1">#, &quot;--+&quot;]:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Lagged links can only be in [&#39;--&gt;&#39;, &#39;&lt;-&gt;&#39;, &#39;---&#39;, &#39;+-&gt;&#39;]&quot;</span>
                    <span class="p">)</span>

            <span class="k">if</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
            <span class="k">elif</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;&lt;--&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
            <span class="k">elif</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;&lt;-&gt;&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="n">links</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">latent_index</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">elif</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;---&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="n">selection_vars</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">latent_index</span><span class="p">)</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                <span class="n">latent_index</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">elif</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;+-&gt;&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="n">links</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">latent_index</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">elif</span> <span class="n">edge_type</span> <span class="o">==</span> <span class="s2">&quot;&lt;-+&quot;</span><span class="p">:</span>
                <span class="n">links</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">latent_index</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="n">links</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">latent_index</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">latent_index</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="c1"># elif edge_type == &quot;+--&quot;:</span>
            <span class="c1">#     links[i].append((j, -tau))</span>
            <span class="c1">#     links[latent_index] = []</span>
            <span class="c1">#     selection_vars.append(latent_index)</span>
            <span class="c1">#     links[latent_index].append((i, -tau))</span>
            <span class="c1">#     links[latent_index].append((j, 0))</span>
            <span class="c1">#     latent_index += 1</span>
            <span class="c1"># elif edge_type == &quot;--+&quot;:</span>
            <span class="c1">#     links[j].append((i, -tau))</span>
            <span class="c1">#     links[latent_index] = []</span>
            <span class="c1">#     selection_vars.append(latent_index)</span>
            <span class="c1">#     links[latent_index].append((i, -tau))</span>
            <span class="c1">#     links[latent_index].append((j, 0))</span>
            <span class="c1">#     latent_index += 1</span>

        <span class="k">return</span> <span class="n">links</span><span class="p">,</span> <span class="n">observed_vars</span><span class="p">,</span> <span class="n">selection_vars</span></div>

    <span class="k">def</span> <span class="nf">_get_minmax_lag</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">links</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function to retrieve tau_min and tau_max from links</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">links</span><span class="p">)</span>

        <span class="c1"># Get maximum time lag</span>
        <span class="n">min_lag</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">inf</span>
        <span class="n">max_lag</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">link_props</span> <span class="ow">in</span> <span class="n">links</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">link_props</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
                    <span class="n">coeff</span> <span class="o">=</span> <span class="n">link_props</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="o">=</span> <span class="n">link_props</span>
                    <span class="n">coeff</span> <span class="o">=</span> <span class="mf">1.</span>                
                <span class="c1"># func = link_props[2]</span>
                <span class="k">if</span> <span class="n">coeff</span> <span class="o">!=</span> <span class="mf">0.</span><span class="p">:</span>
                    <span class="n">min_lag</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">min_lag</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">lag</span><span class="p">))</span>
                    <span class="n">max_lag</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">max_lag</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">lag</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">min_lag</span><span class="p">,</span> <span class="n">max_lag</span>

<div class="viewcode-block" id="OracleCI.get_graph_from_links"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.get_graph_from_links">[docs]</a>    <span class="k">def</span> <span class="nf">get_graph_from_links</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Constructs graph (DAG or MAG or ADMG) from links, observed_vars, </span>
<span class="sd">        and selection_vars.</span>

<span class="sd">        For ADMGs uses the Latent projection operation (Pearl 2009).</span>

<span class="sd">        &quot;&quot;&quot;</span>

        <span class="c1"># TODO: use MAG from DAG construction procedure (lecture notes)</span>
        <span class="c1"># issues with tau_max?</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_is_mag</span> <span class="ow">is</span> <span class="kc">False</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;ADMGs do not support selection_vars.&quot;</span><span class="p">)</span>

        <span class="n">N_all</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>

        <span class="c1"># If tau_max is None, compute from links_coeffs</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">max_lag_links</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_minmax_lag</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">links</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">tau_max</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">tau_max</span> <span class="o">=</span> <span class="n">max_lag_links</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">max_lag_links</span> <span class="o">&gt;</span> <span class="n">tau_max</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;tau_max must be &gt;= maximum lag in links_coeffs; choose tau_max=None&quot;</span><span class="p">)</span>

        <span class="c1"># print(&quot;max_lag_links &quot;, max_lag_links)</span>

        <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">)</span>

        <span class="c1"># Init graph</span>
        <span class="n">graph</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="s1">&#39;&lt;U3&#39;</span><span class="p">)</span>
        <span class="n">graph</span><span class="p">[:]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
        <span class="c1"># We will enumerate the observed variables with (i,j) which refers to the index in MAG graph</span>
        <span class="c1"># while x, y iterates through the variables in the underlying DAG</span>

        <span class="c1"># Loop over the observed variables</span>
        <span class="k">for</span> <span class="n">j</span><span class="p">,</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">):</span>
          <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
              <span class="k">if</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span> <span class="o">!=</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>

                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_is_mag</span><span class="p">:</span>
                    <span class="n">dag_anc_y</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_non_blocked_ancestors</span><span class="p">(</span><span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                                            <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;max_lag&#39;</span><span class="p">,</span>
                                            <span class="n">max_lag</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>
                    <span class="c1"># Only consider observed ancestors</span>
                    <span class="n">mag_anc_y</span> <span class="o">=</span> <span class="p">[</span><span class="n">anc</span> <span class="k">for</span> <span class="n">anc</span> <span class="ow">in</span> <span class="n">dag_anc_y</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span> 
                                <span class="k">if</span> <span class="n">anc</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>

                    <span class="n">dag_anc_x</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_non_blocked_ancestors</span><span class="p">(</span><span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)],</span> 
                                    <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;max_lag&#39;</span><span class="p">,</span>
                                    <span class="n">max_lag</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>
                    
                    <span class="c1"># Only consider observed ancestors</span>
                    <span class="n">mag_anc_x</span> <span class="o">=</span> <span class="p">[</span><span class="n">anc</span> <span class="k">for</span> <span class="n">anc</span> <span class="ow">in</span> <span class="n">dag_anc_x</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)]</span> 
                                <span class="k">if</span> <span class="n">anc</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>   

                    <span class="c1"># Add selection variable ancestors</span>
                    <span class="n">dag_anc_s</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
                    <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">selection_vars</span><span class="p">:</span>
                        <span class="n">dag_anc_s_here</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_non_blocked_ancestors</span><span class="p">(</span><span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">s</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> 
                                    <span class="n">conds</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;max_lag&#39;</span><span class="p">,</span>
                                    <span class="n">max_lag</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>
                        <span class="n">dag_anc_s</span> <span class="o">=</span> <span class="n">dag_anc_s</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">dag_anc_s_here</span><span class="p">[(</span><span class="n">s</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]))</span>
                    
                    <span class="n">dag_anc_s</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">dag_anc_s</span><span class="p">)</span>
                    <span class="c1"># Only consider observed ancestors</span>
                    <span class="n">mag_anc_s</span> <span class="o">=</span> <span class="p">[</span><span class="n">anc</span> <span class="k">for</span> <span class="n">anc</span> <span class="ow">in</span> <span class="n">dag_anc_s</span> 
                                <span class="k">if</span> <span class="n">anc</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span><span class="p">]</span>

                    <span class="n">Z</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">z</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">mag_anc_y</span> <span class="o">+</span> <span class="n">mag_anc_x</span> <span class="o">+</span> <span class="n">mag_anc_s</span> <span class="k">if</span> <span class="n">z</span> <span class="o">!=</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="n">z</span> <span class="o">!=</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)])</span>
                    <span class="n">Z</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">Z</span><span class="p">)</span>
                    
                    <span class="n">separated</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_dsep</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)],</span> <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
                    
                    <span class="c1"># If X and Y are connected given Z, mark a link</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="n">separated</span><span class="p">:</span>
                        <span class="c1"># (i, -tau) --&gt; j</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="n">dag_anc_y</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span> <span class="ow">and</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">dag_anc_x</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;--&gt;&quot;</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;--&quot;</span>

                        <span class="k">elif</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">dag_anc_y</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span> <span class="ow">and</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">dag_anc_x</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-&gt;&quot;</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-&gt;&quot;</span>

                        <span class="k">elif</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="n">dag_anc_y</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span> <span class="ow">and</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">dag_anc_x</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)]</span> <span class="o">+</span> <span class="n">dag_anc_s</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;---&quot;</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;---&quot;</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">j</span> <span class="o">&gt;=</span> <span class="n">i</span><span class="p">:</span>
                        <span class="k">continue</span>
                    <span class="c1"># edge_types = [&quot;--&gt;&quot;, &quot;&lt;-&gt;&quot;, &quot;+-&gt;&quot;]</span>
                    <span class="c1"># Latent projection operation:</span>
                    <span class="c1"># (i)  ADMG contains i --&gt; j iff there is a directed path x --&gt; ... --&gt; y on which</span>
                    <span class="c1">#      every non-endpoint vertex is in hidden variables (= not in observed_vars)</span>
                    <span class="c1"># (ii) ADMG contains i &lt;-&gt; j iff there exists a path of the form x &lt;-- ... --&gt; y on</span>
                    <span class="c1">#      which every non-endpoint vertex is non-collider AND in L (=not in observed_vars)</span>
                    <span class="n">observed_varslags</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([(</span><span class="n">v</span><span class="p">,</span> <span class="o">-</span><span class="n">lag</span><span class="p">)</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">observed_vars</span>
                                                   <span class="k">for</span> <span class="n">lag</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)])</span> <span class="o">-</span> <span class="nb">set</span><span class="p">([(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">),</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)])</span>
                    <span class="n">cond_one_xy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)],</span> <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> 
                        <span class="n">conds</span><span class="o">=</span><span class="p">[],</span> 
                        <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                        <span class="n">starts_with</span><span class="o">=</span><span class="s1">&#39;tail&#39;</span><span class="p">,</span>
                        <span class="n">ends_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>
                        <span class="n">directed</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>  
                        <span class="n">forbidden_nodes</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">observed_varslags</span><span class="p">),</span> 
                        <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                        <span class="n">cond_one_yx</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> 
                            <span class="n">conds</span><span class="o">=</span><span class="p">[],</span> 
                            <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                            <span class="n">starts_with</span><span class="o">=</span><span class="s1">&#39;tail&#39;</span><span class="p">,</span>
                            <span class="n">ends_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>
                            <span class="n">directed</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>  
                            <span class="n">forbidden_nodes</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">observed_varslags</span><span class="p">),</span> 
                            <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">cond_one_yx</span> <span class="o">=</span> <span class="kc">False</span>
                    <span class="n">cond_two</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)],</span> <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">y</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> 
                        <span class="n">conds</span><span class="o">=</span><span class="p">[],</span> 
                        <span class="n">max_lag</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                        <span class="n">starts_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>
                        <span class="n">ends_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>
                        <span class="n">directed</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>  
                        <span class="n">forbidden_nodes</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">observed_varslags</span><span class="p">),</span> 
                        <span class="n">return_path</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">cond_one_xy</span> <span class="ow">and</span> <span class="n">cond_one_yx</span><span class="p">:</span>
                        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Cyclic graph!&quot;</span><span class="p">)</span>
                    <span class="c1"># print((x, -tau), y, cond_one_xy, cond_one_yx, cond_two)</span>

                    <span class="c1"># Only (i) holds: i --&gt; j</span>
                    <span class="k">if</span> <span class="n">cond_one_xy</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">cond_two</span><span class="p">:</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;--&gt;&quot;</span>
                        <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;--&quot;</span>
                    <span class="k">elif</span> <span class="n">cond_one_yx</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">cond_two</span><span class="p">:</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;--&quot;</span>
                        <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;--&gt;&quot;</span>

                    <span class="c1"># Only (ii) holds: i &lt;-&gt; j</span>
                    <span class="k">elif</span> <span class="ow">not</span> <span class="n">cond_one_xy</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">cond_one_yx</span> <span class="ow">and</span> <span class="n">cond_two</span><span class="p">:</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-&gt;&quot;</span>
                        <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-&gt;&quot;</span>

                    <span class="c1"># Both (i) and (ii) hold: i +-&gt; j</span>
                    <span class="k">elif</span> <span class="n">cond_one_xy</span> <span class="ow">and</span> <span class="n">cond_two</span><span class="p">:</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;+-&gt;&quot;</span>
                        <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-+&quot;</span>
                    <span class="k">elif</span> <span class="n">cond_one_yx</span> <span class="ow">and</span> <span class="n">cond_two</span><span class="p">:</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;-+&quot;</span>
                        <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;+-&gt;&quot;</span>
                    <span class="c1"># print((i, -tau), j, cond_one_xy, cond_one_yx, cond_two)</span>

        <span class="k">return</span> <span class="n">graph</span></div>

<div class="viewcode-block" id="OracleCI.get_confidence"><a class="viewcode-back" href="../../../index.html#tigramite.independence_tests.oracle_conditional_independence.OracleCI.get_confidence">[docs]</a>    <span class="k">def</span> <span class="nf">get_confidence</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;For compatibility with PCMCI.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        None</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="kc">None</span></div></div>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>

    <span class="kn">import</span> <span class="nn">tigramite.plotting</span> <span class="k">as</span> <span class="nn">tp</span>
    <span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
    <span class="k">def</span> <span class="nf">lin_f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="n">x</span>

    <span class="c1"># Define the stationary DAG</span>
    <span class="n">links</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span> <span class="p">:</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="mi">1</span><span class="p">:</span> <span class="p">[(</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">)],</span> <span class="mi">2</span><span class="p">:</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">)]}</span>
    <span class="n">observed_vars</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>

    <span class="n">oracle</span> <span class="o">=</span> <span class="n">OracleCI</span><span class="p">(</span><span class="n">links</span><span class="o">=</span><span class="n">links</span><span class="p">,</span> 
        <span class="n">observed_vars</span><span class="o">=</span><span class="n">observed_vars</span><span class="p">,</span> 
        <span class="n">graph_is_mag</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
        <span class="c1">#         selection_vars=selection_vars,</span>
        <span class="c1">#     verbosity=2</span>
        <span class="p">)</span>
    <span class="n">graph</span> <span class="o">=</span> <span class="n">oracle</span><span class="o">.</span><span class="n">graph</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">graph</span><span class="p">[:,:,</span><span class="mi">0</span><span class="p">])</span>

    <span class="n">tp</span><span class="o">.</span><span class="n">plot_time_series_graph</span><span class="p">(</span><span class="n">graph</span><span class="o">=</span><span class="n">graph</span><span class="p">,</span> <span class="n">var_names</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
                <span class="n">save_name</span><span class="o">=</span><span class="s2">&quot;tsg.pdf&quot;</span><span class="p">)</span>

    <span class="n">X</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span>
    <span class="n">Y</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span>
    <span class="n">Z</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="c1"># node = (3, 0)</span>
    <span class="c1"># prelim_Oset = set([(3, 0)])</span>
    <span class="c1"># S = set([])</span>
    <span class="c1"># collider_path_nodes = set([])</span>
    <span class="n">path</span> <span class="o">=</span> <span class="n">oracle</span><span class="o">.</span><span class="n">_has_any_path</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="o">=</span><span class="n">Y</span><span class="p">,</span> 
                            <span class="n">conds</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> 
                            <span class="n">max_lag</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span> 
                            <span class="n">starts_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>
                            <span class="n">ends_with</span><span class="o">=</span><span class="s1">&#39;arrowhead&#39;</span><span class="p">,</span>  
                            <span class="n">forbidden_nodes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                            <span class="n">return_path</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>

    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;-------------------------------&quot;</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">oracle</span><span class="o">.</span><span class="n">_get_maximum_possible_lag</span><span class="p">(</span><span class="n">X</span><span class="o">+</span><span class="n">Z</span><span class="p">))</span> <span class="c1">#(X = X, Y = Y, Z = Z))</span>

    <span class="c1"># cond_ind_test = OracleCI(graph=graph)</span>
    <span class="c1"># links, observed_vars, selection_vars = cond_ind_test.get_links_from_graph(graph)</span>
    <span class="c1"># print(&quot;{&quot;)</span>
    <span class="c1"># for j in links.keys():</span>
    <span class="c1">#     parents = repr([(p, &#39;coeff&#39;, &#39;lin_f&#39;) for p in links[j]])</span>
    <span class="c1">#     print(f&quot;{j: 1d}&quot; &quot;:&quot;  f&quot;{parents:s},&quot;)</span>
    <span class="c1"># print(repr(observed_vars))</span>
    <span class="c1"># cond_ind_test = OracleCI(graph=graph, verbosity=2)</span>

    <span class="c1"># X = [(0, 0)]</span>
    <span class="c1"># Y = [(2, 0)]</span>
    <span class="c1"># Z = [(7, 0), (3, 0), (6, 0), (5, 0), (4, 0)] #(1, -3), (1, -2), (0, -2), (0, -1), (0, -3)]</span>
    <span class="c1"># #(j, -2) for j in range(N)] + [(j, 0) for j in range(N)]</span>

    <span class="c1"># # print(oracle._get_non_blocked_ancestors(Z, Z=None, mode=&#39;max_lag&#39;,</span>
    <span class="c1"># #                                     max_lag=2))</span>
    <span class="c1"># # cond_ind_test = OracleCI(links, observed_vars=observed_vars, verbosity=2)</span>

    <span class="c1"># print(cond_ind_test.get_shortest_path(X=X, Y=Y, Z=Z,</span>
    <span class="c1">#              max_lag=None, compute_ancestors=False, </span>
    <span class="c1">#              backdoor=True))</span>
   
    <span class="c1"># anc_x=None  #oracle.anc_all_x[X[0]]</span>
    <span class="c1"># anc_y=None #oracle.anc_all_y[Y[0]]</span>
    <span class="c1"># anc_xy=None # []</span>
    <span class="c1"># # # for z in Z:</span>
    <span class="c1"># # #     anc_xy += oracle.anc_all_z[z]</span>
    
    <span class="c1"># fig, ax = tp.plot_tsg(links, </span>
    <span class="c1">#             X=[(observed_vars[x[0]], x[1]) for x in X], </span>
    <span class="c1">#             Y=[(observed_vars[y[0]], y[1]) for y in Y], </span>
    <span class="c1">#             Z=[(observed_vars[z[0]], z[1]) for z in Z],</span>
    <span class="c1">#     anc_x=anc_x, anc_y=anc_y, </span>
    <span class="c1">#     anc_xy=anc_xy)</span>

    <span class="c1"># fig.savefig(&quot;/home/rung_ja/Downloads/tsg.pdf&quot;)</span>
</pre></div>

          </div>
          
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Tigramite</a></h1>








<h3>Navigation</h3>

<div class="relations">
<h3>Related Topics</h3>
<ul>
  <li><a href="../../../index.html">Documentation overview</a><ul>
  <li><a href="../../index.html">Module code</a><ul>
  </ul></li>
  </ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>document.getElementById('searchbox').style.display = "block"</script>








        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="footer">
      &copy;2023, Jakob Runge.
      
      |
      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.0.2</a>
      &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
      
    </div>

    

    
  </body>
</html>